package com.pioneer.swing.controller;

import com.pioneer.swing.ui.*;
import com.pioneer.swing.model.*;
import com.pioneer.dao.*;
import com.pioneer.beans.*;

import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import java.util.List;
import java.util.Set;
import java.util.HashSet;


/**
 * Title:        Pioneer Metals Application
 * Description:
 * Copyright:    Copyright (c) 2001
 * Company:      Pioneer Metals
 * @author Gary Chen
 * @version 1.0
 */

public class Validator {
	
	private final static double SALES_MARGIN = 0.28;
	private static ErrorCode handleJobEntry(JInternalFrame frame,JobDAO dao) {
		JobEntryFrame jobEntryFrame=(JobEntryFrame)frame;
		if (jobEntryFrame.jobNameTextField.getText().trim().equals("")) {
			return new ErrorCode(ErrorCode.MISSING_VALUE,"You must enter a job name");
		}
		String state = jobEntryFrame.stateTextField.getText().trim();		
		if (state.length()!=2) {
			return new ErrorCode(ErrorCode.MISSING_VALUE,"You must enter a value 2 character value for state");
		}
		else {			
			jobEntryFrame.stateTextField.setText(state);
		}
		boolean isNew=jobEntryFrame.quoteNumTextField.isEditable();		
		if (isNew) {
			String quoteNum=jobEntryFrame.quoteNumTextField.getText();
				try {
					Job job = dao.getJob(quoteNum);					
					if (job!=null) {						
						return new ErrorCode(ErrorCode.DUPLICATE_KEY,"Please enter a unique quote ID. The one you entered already exists.");
					}
				}
				catch (DataAccessException ex) {
					System.err.println("Couldn't check for primary key of quote ID because "+ex.getMessage());
				}			
		}		
		try {
			Integer.parseInt(jobEntryFrame.numOfUnitsTextField.getText());
		}
		catch (NumberFormatException ex) {
				return new ErrorCode(ErrorCode.BAD_FORMAT,"The units field needs to be a number");
		}
		String jobDateString=jobEntryFrame.jobDateTextField.getText();
		String shipDateString=jobEntryFrame.shipDateTextField.getText();
		try {
			Job testJob = new Job();
			testJob.setJobDate(jobDateString);
			//Job testJob = new Job(null,	jobDateString, null, null, null, null, null, null, "-1", null, null, null, null, shipDateString, null);			
			//long start=testJob.getJobDate().getTime();
			testJob.setShipDate(shipDateString);			
			//long end=testJob.getShipDate().getTime();
			if (testJob.getJobDate()==null) {
				return new ErrorCode(ErrorCode.BAD_FORMAT,"The job date must be entered.");
			}
		}
		catch (java.text.ParseException ex) {
			return new ErrorCode(ErrorCode.BAD_FORMAT,"The date needs to be entered in format MM/DD/YYYY");
		}
		// validate prices
		if (jobEntryFrame.itemsTable.getModel() instanceof ItemEntryTable) {
			try {				
				ItemEntryTable tableModel = (ItemEntryTable)jobEntryFrame.itemsTable.getModel();
				if (tableModel.isPriceModified()) {
					System.out.println("Price was modified.");
					int rowCount = tableModel.getRowCount();
					for (int row=0;row<rowCount;row++) {
						Object itemObj = tableModel.getValueAt(row,tableModel.ITEM_NUM);
						if ((itemObj!=null) && (!itemObj.toString().equals(""))) {						
							Item item = dao.getItem(itemObj.toString());
							if (item==null) {
								return new ErrorCode(ErrorCode.BUSINESS_LOGIC,"Sorry but the item "+
									itemObj.toString()+" is not in the database.");
							}
							double cost = item.getCost();
							int qty = ((Integer)tableModel.getValueAt(row,tableModel.ITEM_QTY)).intValue();
							double price = ((Double)tableModel.getValueAt(row,tableModel.ITEM_PRICE )).doubleValue();
							double totalSale = (double)price*qty;
							double totalCost = (double)cost*qty;
							if ((totalSale - totalCost)/totalSale < SALES_MARGIN) {
								double reqPrice = (double)totalCost/(1-SALES_MARGIN)/qty;
								return new ErrorCode(ErrorCode.BUSINESS_LOGIC,"The unit price for "+
									itemObj.toString()+" should be greater than "+tableModel.rounder(reqPrice));
							}
						}				
					}
				}
				else {
					System.out.println("Price not modified, skipping item validation");
				}
			}
			catch (Exception ex) {
				ex.printStackTrace(System.err);
			}
		}
		return new ErrorCode(ErrorCode.OK,"Everything ok in handle job entry");
	}
	
	private static String removeCommas(String oldStr){
		return oldStr.replaceAll(",","");
	}
	
	private static ErrorCode handleContainerEntry(JInternalFrame frame,ManifestDAO dao) {
		    ContainerEntryFrame containerEntryFrame=(ContainerEntryFrame)frame;
			boolean isNew=containerEntryFrame.containerIdTextField.isEditable();
			if (isNew) {
				String jobNum=containerEntryFrame.jobNumLabel.getText();
				String containerId=containerEntryFrame.containerIdTextField.getText();
				try {
					List containerContentsList=dao.getContainerContents(jobNum,containerId);
					if (containerContentsList.size()>0) {
						// this means there are already contents with the same container ID
						return new ErrorCode(ErrorCode.DUPLICATE_KEY,"Please enter a unique container ID. The one you entered already exists.");
					}
				}
				catch (DataAccessException ex) {
					System.err.println("Couldn't check for primary key of container ID because "+ex.getMessage());
				}
			}
			ContainerEntryTable tableModel=(ContainerEntryTable)containerEntryFrame.containerContentTable.getModel();
			int totalRows=tableModel.getRowCount();
			Set uniqueSet=new HashSet();
			StringBuffer errMessages=new StringBuffer();
			for (int count=0;count<totalRows;count++){
				Object obj=tableModel.getValueAt(count,0);
				if (obj!=null) {
					String description=tableModel.getValueAt(count,0).toString().trim();
					if (description.length()>0) {
						if (!uniqueSet.add(description)) {
							errMessages.append("Description "+description+" is a duplicate entry.\n");
						}
					}
				}
			}
			if (errMessages.length()>0) {
				return new ErrorCode(ErrorCode.DUPLICATE_KEY,errMessages.toString());
			}
		return new ErrorCode(ErrorCode.OK,"Everything ok");
	}

		private static ErrorCode handleManifestEntry(JInternalFrame frame,ManifestDAO dao) {
		    ManifestEntryFrame manifestEntryFrame=(ManifestEntryFrame)frame;
			boolean isNew=manifestEntryFrame.jobTextField.isEditable();
			if (isNew) {
				String jobNum=manifestEntryFrame.jobTextField.getText();
				try {
					Manifest manifest=dao.getManifest(jobNum);
					if (manifest!=null) {
						// this means there are already contents with the same container ID
						return new ErrorCode(ErrorCode.DUPLICATE_KEY,"Please enter a unique job ID. The one you entered already exists.");
					}
				}
				catch (DataAccessException ex) {
					System.err.println("Couldn't check for primary key of container ID because "+ex.getMessage());
				}
			}
			/*
			public Manifest(String jobNum,	String vessel,	String etdString,
	String etaString, String containerNotes, String freightString
			*/
			String etdString=manifestEntryFrame.etdTextField.getText();
			String etaString=manifestEntryFrame.etaTextField.getText();
			manifestEntryFrame.freightTextField.setText(removeCommas(manifestEntryFrame.freightTextField.getText()));
			manifestEntryFrame.truckingTextField.setText(removeCommas(manifestEntryFrame.truckingTextField.getText()));
			manifestEntryFrame.miscTextField.setText(removeCommas(manifestEntryFrame.miscTextField.getText()));
			
			String freightString=manifestEntryFrame.freightTextField.getText();
			
			try {
				Manifest testManifest=new Manifest(null,null,null,etdString,etaString,null,
					manifestEntryFrame.freightTextField.getText(),
					manifestEntryFrame.truckingTextField.getText(),
					manifestEntryFrame.miscTextField.getText());
				long start=testManifest.getEtd().getTime();
				long end=testManifest.getEta().getTime();
				if (start>end) {
					return new ErrorCode(ErrorCode.BAD_FORMAT,"The ETA date cannot be before the ETD date.");
				}
			}
			catch (java.text.ParseException ex) {
				return new ErrorCode(ErrorCode.BAD_FORMAT,"The date needs to be entered in format MM/DD/YYYY");
			}
			catch (NumberFormatException ex) {
				return new ErrorCode(ErrorCode.BAD_FORMAT,"The charges needs to be a number");
			}
		return new ErrorCode(ErrorCode.OK,"Everything ok");
	}
	
	public static ErrorCode validate(JInternalFrame frame,JobDAO dao) {
		if (frame.getName().equals(UIConstants.TITLE_JOB_ENTRY)) {
			return handleJobEntry(frame,dao);
		}
		return new ErrorCode(ErrorCode.OK,"Everything ok");
	}
		
	public static ErrorCode validate(JInternalFrame frame,ManifestDAO dao) {
		if (frame.getName().equals(UIConstants.TITLE_CONTAINER_ENTRY)) {
			return handleContainerEntry(frame,dao);
		}
		if (frame.getName().equals(UIConstants.TITLE_MANIFEST_ENTRY)) {
			return handleManifestEntry(frame,dao);
		}
		return new ErrorCode(ErrorCode.OK,"Everything ok");
	}

}